import envConfig from '@/config/env'
import { API_CONFIG, type ApiResponse, type RequestConfig } from '@/config/api'
import { useMemberStore } from '@/stores/modules/member'

// 刷新令牌状态
let isRefreshing = false
let refreshSubscribers: Array<(token: string) => void> = []

// 添加刷新令牌订阅
const subscribeTokenRefresh = (callback: (token: string) => void) => {
  refreshSubscribers.push(callback)
}

// 触发所有订阅者
const onTokenRefreshed = (token: string) => {
  refreshSubscribers.forEach((callback) => callback(token))
  refreshSubscribers = []
}

// 请求拦截器
const requestInterceptor = (config: RequestConfig) => {
  // 添加认证token
  const token = uni.getStorageSync('token')
  if (token) {
    config.header = {
      ...config.header,
      satoken: token, // Sa-Token 框架使用的 header
      Authorization: `Bearer ${token}`, // 标准 Bearer Token
    }
  }

  // 添加用户信息到请求头
  try {
    // 从 Pinia store 获取用户信息
    const memberStore = useMemberStore()
    const userInfo = memberStore.profile

    if (userInfo && userInfo.id) {
      config.header = {
        ...config.header,
        'X-User-Id': String(userInfo?.id),
        'X-Username': encodeURIComponent(userInfo?.username || ''),
        'X-Real-Name': encodeURIComponent(
          userInfo?.nickname || userInfo?.realName || userInfo?.name || '',
        ),
      }

      // 添加单位信息
      if (userInfo.companyId) {
        config.header['X-Company-Id'] = String(userInfo.companyId)
      }

      if (userInfo.companyName) {
        config.header['X-Company-Name'] = encodeURIComponent(userInfo.companyName || '')
      }

      // 添加当前角色信息
      const currentRoleId = uni.getStorageSync('currentRoleId')
      if (currentRoleId) {
        config.header['X-Role-Id'] = String(currentRoleId)

        // 查找角色名称
        if (userInfo.roles && Array.isArray(userInfo.roles)) {
          const currentRole = userInfo.roles.find((role: any) => role.id === currentRoleId)
          if (currentRole && currentRole.roleName) {
            config.header['X-Role-Name'] = encodeURIComponent(currentRole.roleName)
          }
        }
      }
    }
  } catch (error) {
    // 静默处理错误
  }

  // 添加平台标识
  config.header = {
    ...config.header,
    'X-Platform': getPlatform(),
    'X-Version': envConfig.version,
  }

  return config
}

// 响应拦截器
const responseInterceptor = (response: any): ApiResponse => {
  const { statusCode, data } = response

  // 处理HTTP状态码
  if (statusCode === API_CONFIG.statusCode.SUCCESS) {
    // HTTP 200 成功，但需要检查业务逻辑状态码
    if (data && typeof data === 'object') {
      // 检查业务状态码是否为 401（未授权）
      if (data.code === 401 || (data.message && data.message.includes('暂未登录或token已经过期'))) {
        console.log('[responseInterceptor] 检测到业务状态码401或token过期消息')
        const error: any = new Error(data.message || API_CONFIG.errorMessages.UNAUTHORIZED)
        error.isUnauthorized = true
        throw error
      }
      // 如果后端返回的业务状态码不是成功状态
      if (data.code && data.code !== 200) {
        throw new Error(data.message || '业务处理失败')
      }
      // 业务逻辑成功，返回数据
      return data
    }
    return data
  } else if (statusCode === API_CONFIG.statusCode.UNAUTHORIZED) {
    // 抛出401错误，由主请求函数处理令牌刷新
    console.log('[responseInterceptor] 检测到HTTP状态码401')
    const error: any = new Error(API_CONFIG.errorMessages.UNAUTHORIZED)
    error.isUnauthorized = true
    throw error
  } else if (statusCode === API_CONFIG.statusCode.FORBIDDEN) {
    throw new Error(API_CONFIG.errorMessages.FORBIDDEN)
  } else if (statusCode === API_CONFIG.statusCode.NOT_FOUND) {
    throw new Error(API_CONFIG.errorMessages.NOT_FOUND)
  } else if (statusCode >= 500) {
    throw new Error(API_CONFIG.errorMessages.SERVER_ERROR)
  } else {
    throw new Error(data?.message || '请求失败')
  }
}

// 获取平台标识
const getPlatform = (): string => {
  // #ifdef H5
  return 'H5'
  // #endif

  // #ifdef MP-WEIXIN
  return 'MP-WEIXIN'
  // #endif

  // #ifdef APP-PLUS
  return 'APP'
  // #endif

  return 'UNKNOWN'
}

// 刷新令牌
const refreshToken = async (): Promise<string | null> => {
  try {
    const refreshTokenValue = uni.getStorageSync('refreshToken')
    if (!refreshTokenValue) {
      console.warn('[refreshToken] 没有 refreshToken，无法刷新')
      return null
    }

    console.log('[refreshToken] 开始刷新令牌...')

    // 调用刷新令牌接口
    const response = await new Promise<any>((resolve, reject) => {
      uni.request({
        url: `${envConfig.baseUrl}/auth/refresh`,
        method: 'POST',
        data: {
          refreshToken: refreshTokenValue,
        },
        header: {
          ...API_CONFIG.defaultHeaders,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        success: (res) => {
          console.log('[refreshToken] 响应:', res)
          if (res.statusCode === 200 && res.data) {
            resolve(res.data)
          } else {
            reject(new Error('刷新令牌失败'))
          }
        },
        fail: (err) => {
          console.error('[refreshToken] 请求失败:', err)
          reject(err)
        },
      })
    })

    if (response.code === 200 && response.data) {
      const newToken = response.data
      // 保存新的 token
      uni.setStorageSync('token', newToken)
      console.log('[refreshToken] 令牌刷新成功，新token已保存')
      return newToken
    } else {
      console.warn('[refreshToken] 刷新令牌失败:', response.message)
      return null
    }
  } catch (error) {
    console.error('[refreshToken] 刷新令牌异常:', error)
    return null
  }
}

// 处理未授权（先尝试刷新令牌）
const handleUnauthorized = async (): Promise<boolean> => {
  // 如果正在刷新，返回失败
  if (isRefreshing) {
    console.log('[handleUnauthorized] 正在刷新中，等待刷新完成')
    return false
  }

  isRefreshing = true

  try {
    const newToken = await refreshToken()

    if (newToken) {
      // 刷新成功，通知所有订阅者
      console.log('[handleUnauthorized] 令牌刷新成功，通知所有订阅者')
      onTokenRefreshed(newToken)
      isRefreshing = false
      return true
    } else {
      // 刷新失败，清除所有凭证并跳转登录页
      console.warn('[handleUnauthorized] 令牌刷新失败，跳转登录页')
      isRefreshing = false

      // 清除本地存储的token
      uni.removeStorageSync('token')
      uni.removeStorageSync('refreshToken')
      uni.removeStorageSync('userInfo')

      // 跳转到登录页
      uni.reLaunch({
        url: '/pages/login/login',
      })

      return false
    }
  } catch (error) {
    console.error('[handleUnauthorized] 处理未授权异常:', error)
    isRefreshing = false

    // 清除本地存储的token
    uni.removeStorageSync('token')
    uni.removeStorageSync('refreshToken')
    uni.removeStorageSync('userInfo')

    // 跳转到登录页
    uni.reLaunch({
      url: '/pages/login/login',
    })

    return false
  }
}

// 显示加载提示
const showLoading = (text: string = '加载中...') => {
  uni.showLoading({
    title: text,
    mask: true,
  })
}

// 隐藏加载提示
const hideLoading = () => {
  uni.hideLoading()
}

// 显示错误提示
const showError = (message: string) => {
  uni.showToast({
    title: message,
    icon: 'none',
    duration: 3000,
  })
}

// 主请求函数（支持自动刷新令牌）
export const request = <T = any>(config: RequestConfig): Promise<ApiResponse<T>> => {
  return new Promise((resolve, reject) => {
    // 内部请求执行函数
    const executeRequest = (retryConfig: RequestConfig) => {
      return new Promise<ApiResponse<T>>((innerResolve, innerReject) => {
        // 请求拦截
        const interceptedConfig = requestInterceptor(retryConfig)

        // 显示加载提示（默认不显示，只在明确设置 showLoading: true 时才显示）
        if (interceptedConfig.showLoading === true) {
          showLoading(interceptedConfig.loadingText)
        }

        // 构建完整URL
        const fullUrl = `${envConfig.baseUrl}${interceptedConfig.url}`

        // 发起请求
        uni.request({
          url: fullUrl,
          method: interceptedConfig.method,
          data: interceptedConfig.data,
          header: {
            ...API_CONFIG.defaultHeaders,
            ...interceptedConfig.header,
          },
          timeout: interceptedConfig.timeout || API_CONFIG.timeout,
          success: (response) => {
            try {
              const result = responseInterceptor(response)
              innerResolve(result)
            } catch (error: any) {
              innerReject(error)
            }
          },
          fail: (error) => {
            let errorMessage = API_CONFIG.errorMessages.NETWORK_ERROR

            if (error.errMsg?.includes('timeout')) {
              errorMessage = API_CONFIG.errorMessages.TIMEOUT_ERROR
            }

            innerReject(new Error(errorMessage))
          },
          complete: () => {
            // 隐藏加载提示
            if (interceptedConfig.showLoading === true) {
              hideLoading()
            }
          },
        })
      })
    }

    // 异步执行请求
    ;(async () => {
      try {
        const result = await executeRequest(config)
        resolve(result)
      } catch (error: any) {
        // 如果是401未授权错误
        if (error.isUnauthorized) {
          console.log('[request] 检测到401错误，尝试刷新令牌')

          // 如果正在刷新令牌，等待刷新完成后重试
          if (isRefreshing) {
            console.log('[request] 等待令牌刷新完成...')
            subscribeTokenRefresh(async (newToken) => {
              try {
                console.log('[request] 令牌刷新完成，重试请求')
                const result = await executeRequest(config)
                resolve(result)
              } catch (retryError: any) {
                showError(retryError.message || '请求失败')
                reject(retryError)
              }
            })
          } else {
            // 尝试刷新令牌
            const refreshed = await handleUnauthorized()

            if (refreshed) {
              // 刷新成功，重试原请求
              try {
                console.log('[request] 令牌刷新成功，重试原请求')
                const result = await executeRequest(config)
                resolve(result)
              } catch (retryError: any) {
                showError(retryError.message || '请求失败')
                reject(retryError)
              }
            } else {
              // 刷新失败，已跳转登录页
              showError('登录已过期，请重新登录')
              reject(error)
            }
          }
        } else {
          // 其他错误，直接显示并拒绝
          showError(error.message || '请求失败')
          reject(error)
        }
      }
    })()
  })
}

// 便捷方法
export const get = <T = any>(url: string, data?: any, config?: Partial<RequestConfig>) => {
  return request<T>({
    url,
    method: 'GET',
    data,
    ...config,
  })
}

export const post = <T = any>(url: string, data?: any, config?: Partial<RequestConfig>) => {
  return request<T>({
    url,
    method: 'POST',
    data,
    ...config,
  })
}

export const put = <T = any>(url: string, data?: any, config?: Partial<RequestConfig>) => {
  return request<T>({
    url,
    method: 'PUT',
    data,
    ...config,
  })
}

export const del = <T = any>(url: string, data?: any, config?: Partial<RequestConfig>) => {
  return request<T>({
    url,
    method: 'DELETE',
    data,
    ...config,
  })
}

// 封装上传文件方法，自动添加请求头
export const uploadFile = <T = any>(options: {
  url: string
  filePath: string
  name: string
  formData?: any
  onProgress?: (progress: number) => void
}): Promise<ApiResponse<T>> => {
  return new Promise((resolve, reject) => {
    // 构建请求配置（复用请求拦截器逻辑）
    const config: RequestConfig = {
      url: options.url,
      method: 'POST',
      header: {},
    }

    // 通过请求拦截器处理，自动添加所有请求头
    const interceptedConfig = requestInterceptor(config)

    // 构建完整URL
    const fullUrl = `${envConfig.baseUrl}${options.url}`

    // 调用 uni.uploadFile
    uni.uploadFile({
      url: fullUrl,
      filePath: options.filePath,
      name: options.name,
      formData: options.formData,
      header: interceptedConfig.header,
      success: (res) => {
        try {
          const data = JSON.parse(res.data)
          // 使用响应拦截器处理
          const result = responseInterceptor({
            statusCode: res.statusCode,
            data: data,
          })
          resolve(result)
        } catch (e) {
          reject(new Error('响应解析失败'))
        }
      },
      fail: (err) => {
        reject(err)
      },
    })
  })
}
